package com.auto.learning.store.core;

import java.util.Arrays;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.j256.ormlite.misc.JavaxPersistence;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.DatabaseTable;
import com.j256.ormlite.table.TableUtils;

public class DatabaseUtil {
	public static final String TAG = "DatabaseUtil.java";

	public enum OPERATION_TYPE {
		ADD,
		DELETE
	}

	/**
	 * 升级表，增加字段
	 * @param db
	 * @param clazz
	 * */
	@SuppressWarnings("unchecked")
	public static void upgradeTable(SQLiteDatabase db, ConnectionSource cs, Class clazz, OPERATION_TYPE type) {
		String tableName = extractTableName(clazz);
		db.beginTransaction();
		try {
			// Rename table
			String tempTableName = tableName + "_temp";
			String sql = "ALTER TABLE " + tableName + " RENAME TO " + tempTableName;
			db.execSQL(sql);
			// Create table
			try {
				sql = (String) TableUtils.getCreateTableStatements(cs, clazz).get(0);
				db.execSQL(sql);
			} catch (Exception e) {
				e.printStackTrace();
				TableUtils.createTable(cs, clazz);
			}
			// Load data
			String columns;
			if (type == OPERATION_TYPE.ADD) {
				columns = Arrays.toString(getColumnNames(db, tempTableName)).replace("[", "").replace("]", "");
			} else if (type == OPERATION_TYPE.DELETE) {
				columns = Arrays.toString(getColumnNames(db, tableName)).replace("[", "").replace("]", "");
			} else {
				throw new IllegalArgumentException("OPERATION_TYPE error");
			}
			sql = "INSERT INTO " +tableName  + " ( " + columns + " ) " + " SELECT " + columns + " FROM " + tempTableName;
			db.execSQL(sql);
			// Drop temp table
			sql = "DROP TABLE IF EXISTS " + tempTableName;
			db.execSQL(sql);
			db.setTransactionSuccessful();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			db.endTransaction();
		}
	}

	/**
	 * 获取表名(ormlite DatabaseTableConfig.java)
	 * @param clazz
	 * @return
	 **/
	private static String extractTableName(Class clazz) {
		DatabaseTable databaseTable = (DatabaseTable) clazz.getAnnotation(DatabaseTable.class);
		String name;
		if (databaseTable != null && databaseTable.tableName() != null 	&& databaseTable.tableName().length() > 0) {
			name = databaseTable.tableName();
		} else {
			name = JavaxPersistence.getEntityName(clazz);
			if (name == null) {
				name = clazz.getSimpleName().toLowerCase();
			}
		}
		return name;
	}

	/**
	 * 获取表的列名
	 * @param db
	 * @param tableName
	 **/
	private static String[] getColumnNames(SQLiteDatabase db, String tableName) {
		String[] columnNames = null;
		Cursor cursor = null;
		try {
			cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
			if (cursor != null) {
				int columnIndex = cursor.getColumnIndex("name");
				if (columnIndex == -1) {
					return null;
				}
				int index = 0;
				columnNames = new String[cursor.getCount()];
				for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
					columnNames[index] = cursor.getString(columnIndex);
					index++;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return columnNames;
	}
}